<script lang="ts" setup>
import { ref, reactive, defineEmits, h, nextTick } from 'vue';

import {
  useVbenModal,
  alert,
  prompt,
  useAlertContext,
  VbenButton,
} from '@vben/common-ui';
import {
  Button,
  message,
  Spin,
  Input,
  Descriptions,
  Image,
} from 'ant-design-vue';
import {
  doMaterialInfo,
  getMaterialCat,
  doMaterialAdd,
  doMaterialEdit,
  doMaterialAgainst,
  doMaterialApproval,
  doMaterialColor,
  doMaterialColorAdd,
  doMaterialCategory,
  doMaterialList,
} from '#/api/material';
import { getSupplyList, getMaterialUnitList } from '#/api/common';
import { useDebounceFn } from '@vueuse/core';
import { upload_file_qiniu } from '#/api/upload';
import { useVbenForm } from '#/adapter/form';

const isDisabled = ref(true);
const materialId = ref<Number>();
const routerData = ref<any>({});
const formData = ref<any>({});
const keyword = ref({
  material_type: '',
  supply_id: '',
  material_color: '',
  material_similar: '',
  unit: '',
});
const submitLoading = ref(false);
const title = ref('');
const emit = defineEmits(['fetch-data']);

const initClear = async () => {
  materialId.value = 0;
  formData.value = {};
  Object.keys(keyword.value).forEach((key: string) => {
    keyword.value[key] = '';
  });
};

const catOption = async () => {
  let res = await getMaterialCat({});
  formApi.updateSchema([
    {
      componentProps: {
        allowClear: true,
        showSearch: true,
        optionFilterProp: 'label',
        options: res.map((item: any) => {
          return { label: item.label, value: item.value };
        }),
      },
      fieldName: 'small_category_id',
    },
  ]);
};

const init = async () => {
  catOption();
};

const handleAgainstToApproval = async (type: string) => {
  if (type == 'approval') {
    await doMaterialApproval({ ids: [materialId.value] });
  } else {
    await doMaterialAgainst({ ids: [materialId.value] });
  }
  message.success('操作成功');
  emit('fetch-data');
  modalApi.close();
};

const fetchData = async () => {
  if (materialId.value) {
    let { row } = await doMaterialInfo({ material_id: materialId.value });
    if (row.temp_imgs) {
      row.temp_imgs = [
        {
          url: import.meta.env.VITE_GLOB_RESOURCES_URL + row.temp_imgs,
          name: row.temp_imgs,
          uid: row.temp_imgs,
          status: 'success',
        },
      ];
    } else {
      row.temp_imgs = [];
    }
    Object.keys(keyword.value).forEach((key: string) => {
      if (row[key]) {
        keyword.value[key] = 'initValue:' + row[key];
      }
    });
    formApi.setValues(row);
    formData.value = row;
  }
};

const disabledOn = async () => {
  isDisabled.value = true;
  formApi.setState({ commonConfig: { disabled: true } });
};
const disabledOff = async () => {
  isDisabled.value = false;
  formApi.setState({ commonConfig: { disabled: false } });
};

const handleClose = async () => {
  modalApi.close();
};

const fetchCategoryOptions = async ({ keyword = '' }: Record<string, any>) => {
  let quick_search = '';
  let initValue = '';
  let initKey = 'material_category.id';

  if (keyword.startsWith('initValue:')) {
    initValue = keyword.replace('initValue:', '');
  } else {
    quick_search = keyword;
  }
  const { list } = await doMaterialCategory({
    quick_search: quick_search,
    page: 1,
    limit: 30,
    initKey: initKey,
    initValue: initValue,
    select: true,
  });

  return list.map((item) => ({
    label: item.name,
    value: item.id,
  }));
};

const fetchSupplyOptions = async ({ keyword = '' }: Record<string, any>) => {
  console.log('启动', keyword);
  let quick_search = '';
  let initValue = '';
  let initKey = 'supply.id';

  if (keyword.startsWith('initValue:')) {
    initValue = keyword.replace('initValue:', '');
  } else {
    quick_search = keyword;
  }
  const { list } = await getSupplyList({
    quick_search: quick_search,
    page: 1,
    limit: 30,
    initKey: initKey,
    initValue: initValue,
    select: true,
  });

  return list.map((item) => ({
    label: item.SupplyNa,
    value: item.id,
  }));
};

const fetchColorOptions = async ({ keyword = '' }: Record<string, any>) => {
  let quick_search = '';
  let initValue = '';
  let initKey = 'material_color.name';

  if (keyword.startsWith('initValue:')) {
    if (initValue) {
      initValue = keyword.replace('initValue:', '').split(',');
    }
  } else {
    quick_search = keyword;
  }
  const { list } = await doMaterialColor({
    quick_search: quick_search,
    page: 1,
    limit: 30,
    initKey: initKey,
    initValue: initValue,
    select: true,
  });
  return list.map((item) => ({
    label: item.name,
    value: item.name,
  }));
};

const fetchMaterialListOptions = async ({
  keyword = '',
}: Record<string, any>) => {
  let quick_search = '';
  let initValue = '';
  let initKey = 'material.material_id';

  if (keyword.startsWith('initValue:')) {
    initValue = keyword.replace('initValue:', '');
    if (initValue) {
      initValue = keyword.replace('initValue:', '').split(',');
    }
  } else {
    quick_search = keyword;
  }
  const { list } = await doMaterialList({
    quick_search: quick_search,
    page: 1,
    limit: 30,
    initKey: initKey,
    initValue: initValue,
    select: true,
  });
  return list.map((item) => ({
    label: item.material_code + '/' + item.material_name,
    value: item.material_id,
  }));
};

const fetchUnitOptions = async ({ keyword = '' }: Record<string, any>) => {
  let quick_search = '';
  let initValue = '';
  let initKey = 'cgunit';

  if (keyword.startsWith('initValue:')) {
    initValue = keyword.replace('initValue:', '').split(',');
  } else {
    quick_search = keyword;
  }
  const { list } = await getMaterialUnitList({
    quick_search: quick_search,
    page: 1,
    limit: 30,
    initKey: initKey,
    initValue: initValue,
    select: true,
  });
  return list.map((item) => ({
    label: item.cgunit,
    value: item.cgunit,
  }));
};

/**
 * 保存表单数据，提交前执行校验与数据清洗
 */
async function onSubmit() {
  const { valid } = await formApi.validate();
  if (valid) {
    submitLoading.value = true;
    try {
      formApi.submitForm;
      let savedata = await formApi.getValues();
      if (savedata.temp_imgs && savedata.temp_imgs.length > 0) {
        let imgs = savedata.temp_imgs.map((item: any) => {
          let imgPath = item.url ? item.url : (item.response ?? '');
          // 剔除环境变量前缀，只保存相对路径
          if (imgPath.startsWith(import.meta.env.VITE_GLOB_RESOURCES_URL)) {
            imgPath = imgPath.replace(
              import.meta.env.VITE_GLOB_RESOURCES_URL,
              '',
            );
          }
          return imgPath;
        });
        savedata.temp_imgs = imgs;
      }
      if (materialId.value) {
        await doMaterialEdit({ ...savedata, material_id: materialId.value });
      } else {
        await doMaterialAdd(savedata);
      }
      message.success('保存成功');
      modalApi.close();
      emit('fetch-data');
    } finally {
      submitLoading.value = false;
    }
  }
}

/**
 * 处理保存按钮点击事件，增加防抖避免重复提交
 */
const handleSubmit = useDebounceFn(async () => {
  await onSubmit();
}, 300);

const handleAddColor = () => {
  prompt<string>({
    async beforeClose({ isConfirm, value }) {
      if (isConfirm && value) {
        await doMaterialColorAdd({ name: value }).then((res) => {
          message.success('添加成功');
          return true;
        });
      }
      return true;
    },
    componentProps: { placeholder: '请输入颜色名称' },
    content: '颜色名称',
    overlayBlur: 3,
  }).catch(() => {
    // message.error('用户取消了输入')
  });
};

const [Modal, modalApi] = useVbenModal({
  class: 'w-4/5',
  appendToMain: true,
  fullscreen: true,
  destroyOnClose: true,
  showConfirmButton: false,
  showCancelButton: false,
  onOpenChange(isOpen: boolean) {
    if (isOpen) {
      routerData.value = modalApi.getData<Record<string, any>>();
      title.value = routerData.value.info ? '编辑' : '新增';
      initClear();
      init();

      if (routerData.value?.info?.material_id) {
        materialId.value = routerData.value?.info?.material_id;
      }

      if (materialId.value) {
        fetchData();
        disabledOn();
      } else {
        disabledOff();
      }
    }
  },
});

const [Form, formApi] = useVbenForm({
  commonConfig: {
    disabled: true,
    componentProps: {
      class: 'w-full',
    },
  },
  showDefaultActions: false,

  layout: 'horizontal',
  schema: [
    {
      component: 'Upload',
      componentProps: {
        accept: '.png,.jpg,.jpeg',
        customRequest: upload_file_qiniu,
        disabled: false,
        maxCount: 1,
        multiple: false,
        showUploadList: true,
        listType: 'picture-card',
      },
      fieldName: 'temp_imgs',
      label: '物料图',
      renderComponentContent: () => {
        return {
          default: () => '点击上传',
        };
      },
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入物料名称',
      },
      fieldName: 'material_name',
      label: '物料名称',
      rules: 'required',
    },

    {
      component: 'ApiSelect',
      componentProps: () => {
        return {
          api: fetchCategoryOptions,
          filterOption: false,
          onSearch: useDebounceFn((value: string) => {
            keyword.value.material_type = value;
          }, 300),
          params: {
            keyword: keyword.value.material_type || undefined,
          },
          showSearch: true,
          immediate: false,
          alwaysLoad: true,
          visibleEvent: 'onFocus',
          onDropdownVisibleChange: (open: boolean) => {
            if (open) keyword.value.material_type = '';
          },
        };
      },
      fieldName: 'material_type',
      label: '类型',
      operator: '=',
      rules: 'selectRequired',
    },
    {
      component: 'Select',
      componentProps: () => {
        return {
          options: [],
          showSearch: true,
        };
      },
      fieldName: 'small_category_id',
      label: '小类',
      operator: '=',
      rules: 'required',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入幅宽',
      },
      fieldName: 'cloth_width',
      label: '幅宽',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入克重',
      },
      fieldName: 'gram_weight',
      label: '克重',
    },

    {
      component: 'ApiSelect',
      componentProps: () => {
        return {
          api: fetchUnitOptions,
          filterOption: false,
          onSearch: useDebounceFn((value: string) => {
            keyword.value.unit = value;
          }, 300),
          params: {
            keyword: keyword.value.unit || undefined,
          },
          onChange: (value: any) => {
            formApi.setValues({ check_unit: value });
          },
          showSearch: true,
          immediate: false,
          alwaysLoad: true,
          visibleEvent: 'onFocus',
          onDropdownVisibleChange: (open: boolean) => {
            if (open) keyword.value.unit = '';
          },
        };
      },
      fieldName: 'unit',
      label: '采购单位',
      operator: '=',
      rules: 'selectRequired',
    },

    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入核料单位',
      },
      fieldName: 'check_unit',
      label: '核料单位',
      rules: 'required',
    },
    {
      component: 'InputNumber',
      componentProps: {
        placeholder: '请输入核算比例',
        step: 1,
      },
      fieldName: 'unit_rate',
      label: '核算比例',
      disabled: true,
      defaultValue: 1,
      rules: 'required',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入成份',
      },
      fieldName: 'material_attr',
      label: '成份',
    },
    {
      component: 'InputNumber',
      componentProps: {
        placeholder: '请输入采购单价',
        step: 0.001,
        onChange: (value: any) => {
          formApi.setValues({ check_price: value });
        },
      },
      fieldName: 'price',
      label: '采购单价',
      rules: 'required',
    },
    {
      component: 'InputNumber',
      componentProps: {
        placeholder: '请输入核料单价',
        step: 0.001,
      },
      fieldName: 'check_price',
      label: '核料单价',
      rules: 'required',
    },
    {
      component: 'InputNumber',
      componentProps: {
        placeholder: '请输入发出单价',
        step: 0.001,
      },
      fieldName: 'send_price',
      label: '发出单价',
    },
    {
      component: 'InputNumber',
      componentProps: {
        placeholder: '请输入成本价',
        step: 0.001,
      },
      fieldName: 'cost_price',
      label: '成本价',
    },
    {
      component: 'ApiSelect',
      componentProps: () => {
        return {
          api: fetchSupplyOptions,
          filterOption: false,
          onSearch: useDebounceFn((value: string) => {
            keyword.value.supply_id = value;
          }, 300),
          // 远程搜索参数。当搜索词变化时，params也会更新
          params: {
            keyword: keyword.value.supply_id || undefined,
          },
          showSearch: true,
          immediate: false,
          alwaysLoad: true,
          visibleEvent: 'onFocus',
          onDropdownVisibleChange: (open: boolean) => {
            if (open) keyword.value.supply_id = '';
          },
        };
      },
      fieldName: 'supply_id',
      label: '供应商',
      operator: '=',
      rules: 'selectRequired',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入供方物料编码',
      },
      fieldName: 'supply_code',
      label: '供方物料编码',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入系列',
      },
      fieldName: 'material_series',
      label: '系列',
    },
    {
      component: 'InputNumber',
      componentProps: {
        placeholder: '请输入空差',
      },
      fieldName: 'gap',
      label: '空差',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入面料等级',
      },
      fieldName: 'material_grade',
      label: '面料等级',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入备注',
      },
      fieldName: 'remark',
      label: '备注',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入备注2',
      },
      fieldName: 'remark_second',
      label: '备注2',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入缩率',
      },
      fieldName: 'no_use_rate',
      label: '缩率',
    },
    {
      component: 'InputNumber',
      componentProps: {
        placeholder: '请输入导出损耗率',
      },
      fieldName: 'exp_loss',
      label: '导出损耗率',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '请输入规格',
      },
      fieldName: 'specs',
      label: '规格',
    },
    {
      component: 'ApiSelect',
      componentProps: () => {
        return {
          api: fetchColorOptions,
          filterOption: false,
          onSearch: useDebounceFn((value: string) => {
            keyword.value.material_color = value;
          }, 300),
          params: {
            keyword: keyword.value.material_color || undefined,
          },
          showSearch: true,
          mode: 'multiple',
          immediate: false,
          alwaysLoad: true,
          visibleEvent: 'onFocus',
          onDropdownVisibleChange: (open: boolean) => {
            if (open) keyword.value.material_color = '';
          },
        };
      },
      fieldName: 'material_color',
      label: '颜色',
      operator: 'IN',
      rules: 'selectRequired',
      suffix: () => h(Button, { onClick: handleAddColor }, () => '+添加颜色'),
    },
    {
      component: 'ApiSelect',
      componentProps: () => {
        return {
          api: fetchMaterialListOptions,
          filterOption: false,
          onSearch: useDebounceFn((value: string) => {
            keyword.value.material_similar = value;
          }, 300),
          params: {
            keyword: keyword.value.material_similar || undefined,
          },
          showSearch: true,
          mode: 'multiple',
          immediate: false,
          alwaysLoad: true,
          visibleEvent: 'onFocus',
        };
      },
      fieldName: 'material_similar',
      label: '类似料',
      operator: 'IN',
      // rules: 'selectRequired', 不必填
    },
  ],
  wrapperClass: 'grid-cols-4',
});
</script>

<template>
  <Modal :title="title">
    <Form />
    <template #prepend-footer>
      <Button @click="handleClose()">取消</Button>
      <template v-if="materialId">
        <Button
          type="ghost"
          class="mr-2 bg-[#24b916] text-white hover:opacity-75"
          @click="
            handleAgainstToApproval(formData.posted ? 'against' : 'approval')
          "
        >
          {{ formData.posted ? '反审' : '审核' }}
        </Button>
        <Button
          v-if="isDisabled && !formData.posted"
          type="ghost"
          class="mr-2 bg-[#f0a62f] text-[#fff] hover:opacity-75"
          @click="disabledOff()"
          >修改</Button
        >
      </template>
      <Button
        v-if="!isDisabled || !materialId"
        type="primary"
        :loading="submitLoading"
        :disabled="submitLoading"
        @click="handleSubmit"
        >保存</Button
      >
    </template>
  </Modal>
</template>
